package com.ruoyi.business.service.impl;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.business.domain.ChapterInfo;
import com.ruoyi.business.domain.TCourseResource;
import com.ruoyi.business.domain.User;
import com.ruoyi.business.domain.bo.CourseVideoBo;
import com.ruoyi.business.domain.vo.CourseVideoVo;
import com.ruoyi.business.enumeration.ResourceEnum;
import com.ruoyi.business.enumeration.ResourceStatusEnum;
import com.ruoyi.business.mapper.ChapterInfoMapper;
import com.ruoyi.business.mapper.TCourseResourceMapper;
import com.ruoyi.business.service.ITCourseResourceService;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.system.domain.SysOss;
import com.ruoyi.system.service.ISysOssService;
import com.sun.org.apache.regexp.internal.RE;
import org.checkerframework.checker.units.qual.C;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.business.mapper.CourseVideoMapper;
import com.ruoyi.business.domain.CourseVideo;
import com.ruoyi.business.service.ICourseVideoService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 小节视频Service业务层处理
 * 
 * @author 最爱喝兽奶
 * @date 2022-08-02
 */
@SuppressWarnings("ALL")
@Service
public class CourseVideoServiceImpl extends ServiceImpl<CourseVideoMapper, CourseVideo> implements ICourseVideoService
{
    @Autowired
    private CourseVideoMapper courseVideoMapper;

    @Autowired
    private ChapterInfoMapper chapterInfoMapper;

    @Autowired
    private ITCourseResourceService courseResourceService;

    @Autowired
    private ISysOssService ossService;

    /**
     * 查询小节视频
     * 
     * @param id 小节视频主键
     * @return 小节视频
     */
    @Override
    public CourseVideoVo selectCourseVideoById(Long id)
    {
        CourseVideo courseVideo = courseVideoMapper.selectById(id);
        return convertVideoToVo(courseVideo);
    }

    /**
     * 查询小节视频列表
     * 
     * @param CourseVideo 小节视频
     * @return 小节视频
     */
    @Override
    public TableDataInfo selectCourseVideoList(CourseVideoBo bo)
    {
        CourseVideo courseVideo = new CourseVideo();
        BeanUtils.copyBeanProp(courseVideo, bo, false);
        Page<CourseVideo> page = courseVideoMapper.selectPage(PageUtils.buildPage(bo), buildQueryWrapper(bo));
        List<CourseVideoVo> vos = page.getRecords().stream().map(item -> {
            return convertVideoToVo(item);
        }).sorted(new Comparator<CourseVideoVo>() {
            @Override
            public int compare(CourseVideoVo o1, CourseVideoVo o2) {
                Long c1 = Long.parseLong(o1.getChapterId());
                Long c2 = Long.parseLong(o2.getChapterId());
                return (int) (c1 - c2);
            }
        }).collect(Collectors.toList());
        Page<CourseVideoVo> convert = PageUtils.convert(page, vos);
        return PageUtils.buildTableDataInfo(convert);
    }

    private LambdaQueryWrapper<CourseVideo> buildQueryWrapper(CourseVideoBo bo) {
        LambdaQueryWrapper<CourseVideo> lqw = new LambdaQueryWrapper<>();
        lqw.like(StringUtils.isNotBlank(bo.getName()), CourseVideo::getName, bo.getName());
        lqw.eq(null != bo.getCourseId(), CourseVideo::getCourseId, bo.getCourseId());
        lqw.eq(null != bo.getChapterId(), CourseVideo::getChapterId, bo.getChapterId());
        return lqw;
    }

    /**
     * 新增小节视频
     * 
     * @param CourseVideo 小节视频
     * @return 结果
     */
    @Override
    @Transactional
    public void insertCourseVideo(CourseVideoBo bo)
    {
        CourseVideo courseVideo = new CourseVideo();
        BeanUtils.copyProperties(bo, courseVideo);
        // 先查询当前小节的最大序号数
        Long sectionNumber = courseVideoMapper.selectMaxSectionNum(courseVideo.getChapterId());
        if (null == sectionNumber) {
            courseVideo.setSectionNumber(0L);
        }else {
            courseVideo.setSectionNumber(sectionNumber + 1);
        }
        // TODO: 目前先屎山代码讲究一下了，插入资源信息
        courseVideoMapper.insert(courseVideo);

        List<TCourseResource> resources = createCourseResourcesByCourseVideo(bo);
        courseResourceService.saveBatch(resources);
        // 插入小节
        chapterInfoMapper.updateVideoNumberById(Long.parseLong(courseVideo.getChapterId()));
    }

    /**
     * 修改小节视频
     * 
     * @param CourseVideo 小节视频
     * @return 结果
     */
    @Transactional
    @Override
    public int updateCourseVideo(CourseVideoBo courseVideoBo)
    {
        CourseVideo courseVideo = new CourseVideo();
        BeanUtils.copyProperties(courseVideoBo, courseVideo);
        List<TCourseResource> resources = createCourseResourcesByCourseVideo(courseVideoBo);
        // 先查询当前小节的最大序号数
        Long sectionNumber = courseVideoMapper.selectMaxSectionNum(courseVideo.getChapterId());
        courseResourceService.remove(new QueryWrapper<TCourseResource>().eq("course_video_id", courseVideo.getId()));
        courseResourceService.saveBatch(resources);
        if (null == sectionNumber) {
            courseVideo.setSectionNumber(0L);
        }else {
            courseVideo.setSectionNumber(sectionNumber + 1);
        }
        return courseVideoMapper.updateById(courseVideo);
    }

    public List<TCourseResource> createCourseResourcesByCourseVideo(CourseVideoBo bo) {
        String video = bo.getVideo();
        List<TCourseResource> resources = new ArrayList<>();
        long currentTime = System.currentTimeMillis();
        if (StringUtils.isNotEmpty(video)) {
            String[] split = video.split(",");
            for (String ossId : split) {
                QueryWrapper<TCourseResource> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("course_video_id", bo.getId());
                queryWrapper.eq("oss_id", ossId);
                TCourseResource resource = courseResourceService.getOne(queryWrapper);
                if (resource != null) {
                    resource.setUpdateTime(currentTime);
                }else {
                    resource = new TCourseResource();
                    SysOss sysOss = ossService.queryById(ossId);
                    String sourceName = sysOss.getOriginalName().substring(0, sysOss.getOriginalName().lastIndexOf("."));
                    resource.setCatagory(ResourceEnum.VIDEO.getValue());
                    resource.setCourseVideoId(Long.valueOf(bo.getId()));
                    resource.setOssId(Long.valueOf(ossId));
                    resource.setCreateTime(currentTime);
                    resource.setUpdateTime(currentTime);
                    resource.setSourceName(sourceName);
                    resource.setFullSourceName(sysOss.getOriginalName());
                    resource.setUpdateBy(SecurityUtils.getUserId());
                    resource.setDownloadNum(0);
                    resource.setStatus(ResourceStatusEnum.REVIEWING.getValue());
                }
                resources.add(resource);
            }
        }

        String pictures = bo.getPictures();
        if (StringUtils.isNotEmpty(pictures)) {
            String[] split = pictures.split(",");
            for (String ossId : split) {
                QueryWrapper<TCourseResource> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("course_video_id", bo.getId());
                queryWrapper.eq("oss_id", ossId);
                TCourseResource resource = courseResourceService.getOne(queryWrapper);
                if (resource != null) {
                    resource.setUpdateTime(currentTime);
                }else {
                    resource = new TCourseResource();
                    SysOss sysOss = ossService.queryById(ossId);
                    String sourceName = sysOss.getOriginalName().substring(0, sysOss.getOriginalName().lastIndexOf("."));
                    resource.setCatagory(ResourceEnum.PICTURE.getValue());
                    resource.setCourseVideoId(Long.valueOf(bo.getId()));
                    resource.setOssId(Long.valueOf(ossId));
                    resource.setCreateTime(currentTime);
                    resource.setUpdateTime(currentTime);
                    resource.setUpdateBy(SecurityUtils.getUserId());
                    resource.setDownloadNum(0);
                    resource.setSourceName(sourceName);
                    resource.setFullSourceName(sysOss.getOriginalName());
                    resource.setStatus(ResourceStatusEnum.REVIEWING.getValue());
                }
                resources.add(resource);
            }
        }

        String ppt = bo.getPpt();
        if (StringUtils.isNotEmpty(ppt)) {
            String[] split = ppt.split(",");
            for (String ossId : split) {
                QueryWrapper<TCourseResource> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("course_video_id", bo.getId());
                queryWrapper.eq("oss_id", ossId);
                TCourseResource resource = courseResourceService.getOne(queryWrapper);
                if (resource != null) {
                    resource.setUpdateTime(currentTime);
                }else {
                    resource = new TCourseResource();
                    SysOss sysOss = ossService.queryById(ossId);
                    String sourceName = sysOss.getOriginalName().substring(0, sysOss.getOriginalName().lastIndexOf("."));
                    resource.setCatagory(ResourceEnum.PPT.getValue());
                    resource.setCourseVideoId(Long.valueOf(bo.getId()));
                    resource.setOssId(Long.valueOf(ossId));
                    resource.setCreateTime(currentTime);
                    resource.setUpdateTime(currentTime);
                    resource.setUpdateBy(SecurityUtils.getUserId());
                    resource.setDownloadNum(0);
                    resource.setSourceName(sourceName);
                    resource.setFullSourceName(sysOss.getOriginalName());
                    resource.setStatus(ResourceStatusEnum.REVIEWING.getValue());
                }

                resources.add(resource);
            }
        }
        return resources;
    }

    /**
     * 批量删除小节视频
     * 
     * @param ids 需要删除的小节视频主键
     * @return 结果
     */
    @Override
    public int deleteCourseVideoByIds(Long[] ids)
    {
        return courseVideoMapper.deleteCourseVideoByIds(ids);
    }

    /**
     * 删除小节视频信息
     * 
     * @param id 小节视频主键
     * @return 结果
     */
    @Override
    public int deleteCourseVideoById(Long id)
    {
        return courseVideoMapper.deleteCourseVideoById(id);
    }

    @Override
    public void moveUp(String id) {
        CourseVideo courseVideo = courseVideoMapper.selectById(id);
        if (null != courseVideo) {
            // 查询下一个id
            CourseVideo pre = courseVideoMapper.selectPreId(courseVideo.getSectionNumber(), courseVideo.getChapterId());
            if (null != pre) {
                move(courseVideo, pre);
            }else {
                throw new RuntimeException("这是第一个不能上移的哦，不能调皮哦!");
            }
        }
    }

    @Override
    public void moveDown(String id) {
        CourseVideo courseVideo = courseVideoMapper.selectById(id);
        if (null != courseVideo) {
            // 查询下一个id
            CourseVideo next = courseVideoMapper.selectNextId(courseVideo.getSectionNumber(), courseVideo.getChapterId());
            if (null != next) {
                move(courseVideo, next);
            }else {
                throw new RuntimeException("已经是最后一个了哦");
            }
        }
    }

    @Override
    public void deleteCourseVideoByChapterId(String chapterInfoId) {
        QueryWrapper<CourseVideo> wrapper = new QueryWrapper<>();
        baseMapper.delete(wrapper);
    }

    public void move(CourseVideo c1, CourseVideo c2) {
        Long temp = c1.getSectionNumber();
        c1.setSectionNumber(c2.getSectionNumber());
        c2.setSectionNumber(temp);
        courseVideoMapper.updateById(c1);
        courseVideoMapper.updateById(c2);
    }

    private CourseVideoVo convertVideoToVo(CourseVideo courseVideo) {
        CourseVideoVo vo = new CourseVideoVo();
        BeanUtils.copyBeanProp(vo, courseVideo, false);
        ChapterInfo chapterInfo = chapterInfoMapper.selectById(vo.getChapterId());
        vo.setChapterName(chapterInfo.getName());
        List<TCourseResource> resources = courseResourceService.list(new QueryWrapper<TCourseResource>().eq("course_video_id", courseVideo.getId()));
        String video = resources.stream().filter(resource -> {
            if (ResourceEnum.VIDEO.getValue().equals(resource.getCatagory())) {
                return true;
            }
            return false;
        }).map(resource -> {
            return String.valueOf(resource.getOssId());
        }).collect(Collectors.joining(","));
        vo.setVideo(video);

        String picture = resources.stream().filter(resource -> {
            if (ResourceEnum.PICTURE.getValue().equals(resource.getCatagory())) {
                return true;
            }
            return false;
        }).map(resource -> {
            return String.valueOf(resource.getOssId());
        }).collect(Collectors.joining(","));
        vo.setPictures(picture);

        String ppt = resources.stream().filter(resource -> {
            if (ResourceEnum.PPT.getValue().equals(resource.getCatagory())) {
                return true;
            }
            return false;
        }).map(resource -> {
            return String.valueOf(resource.getOssId());
        }).collect(Collectors.joining(","));
        vo.setPpt(ppt);
        return vo;
    }
}
